<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Tutorial using Web2Py &mdash; Geraldo Reports Documentation v0.4-alpha-6 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.4-alpha-6',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Geraldo Reports Documentation v0.4-alpha-6 documentation" href="index.html" />
    <link rel="next" title="Basic Reference" href="basic.html" />
    <link rel="prev" title="Tutorial using Django" href="tutorial-1.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="basic.html" title="Basic Reference"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="tutorial-1.html" title="Tutorial using Django"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">Geraldo Reports Documentation v0.4-alpha-6 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="tutorial-using-web2py">
<h1>Tutorial using Web2Py<a class="headerlink" href="#tutorial-using-web2py" title="Permalink to this headline">¶</a></h1>
<p>Once you have Geraldo installed and its dependencies resolved (read the
Installation document to know about the dependencies on ReportLab and Python
Imaging Library), you can start using it from <strong>Web2Py</strong> without any need to adjust settings.</p>
<div class="section" id="step-1-preparing-your-project">
<h2>Step 1. Preparing your project<a class="headerlink" href="#step-1-preparing-your-project" title="Permalink to this headline">¶</a></h2>
<p>Let&#8217;s create a new URL to load a PDF report online.</p>
<p>We are going to work with a common example for this kind of solution: a
purchasing application.</p>
<p>Let&#8217;s say you have the following model:</p>
<div class="highlight-python"><pre>db.define_table(product,
            Field('name', length=100))

db.define_table(customer,
            Field('name', length=100))

db.define_table(purchase,
            Field('customer', db.customer),
            Field('delivery_address', length=70),
            Field('date_creation', 'datetime', default=request.now),
            Field('date_bill', 'date'),
            Field('date_delivery', 'date'),
            Field('taxes', 'float', default=0.00),
            Field('sub_total_price', 'float', default=0.00),
            Field('total_price', 'float', default=0.00)
            )

db.define_table(purchase_item,
            Field('purchase', db.purchase),
            Field('product', db.product),
            Field('unit_price', 'float')
            Field('quantity', 'float')
            Field('total_price', 'float', default=0.00)
            )</pre>
</div>
<p>Add a new function to your Controller, for example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">purchase_report</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">reports</span> <span class="kn">import</span> <span class="n">ReportPurchase</span>
    <span class="kn">from</span> <span class="nn">geraldo.generators</span> <span class="kn">import</span> <span class="n">PDFGenerator</span>
    <span class="kn">import</span> <span class="nn">gluon.contenttype</span>
    <span class="kn">import</span> <span class="nn">StringIO</span>

    <span class="n">resp</span> <span class="o">=</span> <span class="n">StringIO</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>

    <span class="n">purchases</span> <span class="o">=</span> <span class="n">db</span><span class="p">(</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">id</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">orderby</span><span class="o">=</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">customer</span><span class="o">|</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
    <span class="n">report</span> <span class="o">=</span> <span class="n">ReportPurchase</span><span class="p">(</span><span class="n">queryset</span><span class="o">=</span><span class="n">purchases</span><span class="p">)</span>
    <span class="n">report</span><span class="o">.</span><span class="n">generate_by</span><span class="p">(</span><span class="n">PDFGenerator</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="n">resp</span><span class="p">)</span>

    <span class="n">resp</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;Content-Type&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gluon</span><span class="o">.</span><span class="n">contenttype</span><span class="o">.</span><span class="n">contenttype</span><span class="p">(</span><span class="s">&#39;.pdf&#39;</span><span class="p">)</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">_Purchases.pdf&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">server_name</span><span class="p">)</span>
    <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;Content-disposition&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;attachment; filename=</span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">filename</span>
    <span class="k">return</span> <span class="n">resp</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</pre></div>
</div>
<p>You can see you first imported two important things:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">reports</span> <span class="kn">import</span> <span class="n">ReportPurchase</span>
<span class="kn">from</span> <span class="nn">geraldo.generators</span> <span class="kn">import</span> <span class="n">PDFGenerator</span>
</pre></div>
</div>
<p>Your report class (we will create it in the next step) and the generator class
<strong>PDFGenerator</strong> you will need to generate a PDF file.</p>
<p>The next thing to note is that you instantiate a StringIO object to use to return the PDF:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">StringIO</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">StringIO</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
</pre></div>
</div>
<p>Now you are going to work your report instance:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">purchases</span> <span class="o">=</span> <span class="n">db</span><span class="p">(</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">id</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">orderby</span><span class="o">=</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">customer</span><span class="o">|</span><span class="n">db</span><span class="o">.</span><span class="n">purchase</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="n">report</span> <span class="o">=</span> <span class="n">ReportPurchase</span><span class="p">(</span><span class="n">queryset</span><span class="o">=</span><span class="n">purchases</span><span class="p">)</span>
<span class="n">report</span><span class="o">.</span><span class="n">generate_by</span><span class="p">(</span><span class="n">PDFGenerator</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="n">resp</span><span class="p">)</span>
</pre></div>
</div>
<p>Finally you prepare the response:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">resp</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;Content-Type&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gluon</span><span class="o">.</span><span class="n">contenttype</span><span class="o">.</span><span class="n">contenttype</span><span class="p">(</span><span class="s">&#39;.pdf&#39;</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">_Purchases.pdf&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">server_name</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;Content-disposition&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;attachment; filename=</span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">filename</span>
<span class="k">return</span> <span class="n">resp</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</pre></div>
</div>
<ul class="simple">
<li>The first thing you did is to get all purchases, ordered by &#8216;customer&#8217; and &#8216;id&#8217;
fields;</li>
<li>Afterwards, you got a <strong>report</strong> instance from your report class
<strong>ReportPurchase</strong>, using purchases queryset as report driver queryset;</li>
<li>Next, you called the &#8216;generate_by&#8217; method of the generator class.</li>
<li>And last, you prepared the StringIO object to be delivered to the browser.</li>
</ul>
<p>Now you have a prepared Web2Py application to use a report you are going to
create at the next step!</p>
</div>
<div class="section" id="declaring-the-report-class">
<h2>Declaring the report class<a class="headerlink" href="#declaring-the-report-class" title="Permalink to this headline">¶</a></h2>
<p>The report class must be an inheritance from <strong>geraldo.Report</strong> class. You can
create a new file &#8216;reports.py&#8217; to declare your report classes inside.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">geraldo</span> <span class="kn">import</span> <span class="n">Report</span>

<span class="k">class</span> <span class="nc">ReportPurchase</span><span class="p">(</span><span class="n">Report</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;Purchases list&#39;</span>
    <span class="n">author</span> <span class="o">=</span> <span class="s">&#39;John Smith Corporation&#39;</span>
</pre></div>
</div>
<p>To see something more complex, you can set the page size, margins and
other report attributes, like below:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">geraldo</span> <span class="kn">import</span> <span class="n">Report</span><span class="p">,</span> <span class="n">landscape</span>
<span class="kn">from</span> <span class="nn">reportlab.lib.pagesizes</span> <span class="kn">import</span> <span class="n">A5</span>
<span class="kn">from</span> <span class="nn">reportlab.lib.units</span> <span class="kn">import</span> <span class="n">cm</span>

<span class="k">class</span> <span class="nc">ReportPurchase</span><span class="p">(</span><span class="n">Report</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;Purchases list&#39;</span>
    <span class="n">author</span> <span class="o">=</span> <span class="s">&#39;John Smith Corporation&#39;</span>

    <span class="n">page_size</span> <span class="o">=</span> <span class="n">landscape</span><span class="p">(</span><span class="n">A5</span><span class="p">)</span>
    <span class="n">margin_left</span> <span class="o">=</span> <span class="mi">2</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_top</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_right</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_bottom</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
</pre></div>
</div>
<p>As you can see, we use what we can from the ReportLab libraries, their units, page
sizes, stylizing, etc.</p>
<p>A report is driven by <strong>bands</strong>. If you are used to working with other report
engines you know what a band is.</p>
<p>A band is a row with elements in the report canvas. Bands in essence are the
same but their use varies depending whether you are using a band as the Page Header or
Report Summary, for example.</p>
<p>A report can have a band for each one of following attributes:</p>
</div>
<div class="section" id="detail-band">
<h2>Detail band<a class="headerlink" href="#detail-band" title="Permalink to this headline">¶</a></h2>
<p>The detail band is the most important band in a report. This is because the
detail band is the reason of the existence of every report.</p>
<p>The detail band is used most of the time to show object field values. This is the
same for a detailed info page or just a simple list or grid.</p>
<p>The detail band is rendered one time for each object in the queryset attribute.
So, if you have 10 objects in the queryset, you will have the detail band rendered
10 times.</p>
<p>Let&#8217;s change our report to have a detail band, see below:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">geraldo</span> <span class="kn">import</span> <span class="n">Report</span><span class="p">,</span> <span class="n">landscape</span><span class="p">,</span> <span class="n">ReportBand</span><span class="p">,</span> <span class="n">ObjectValue</span>
<span class="kn">from</span> <span class="nn">reportlab.lib.pagesizes</span> <span class="kn">import</span> <span class="n">A5</span>
<span class="kn">from</span> <span class="nn">reportlab.lib.units</span> <span class="kn">import</span> <span class="n">cm</span>

<span class="k">class</span> <span class="nc">ReportPurchase</span><span class="p">(</span><span class="n">Report</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;Purchases list&#39;</span>
    <span class="n">author</span> <span class="o">=</span> <span class="s">&#39;John Smith Corporation&#39;</span>

    <span class="n">page_size</span> <span class="o">=</span> <span class="n">landscape</span><span class="p">(</span><span class="n">A5</span><span class="p">)</span>
    <span class="n">margin_left</span> <span class="o">=</span> <span class="mi">2</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_top</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_right</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
    <span class="n">margin_bottom</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>

    <span class="k">class</span> <span class="nc">band_detail</span><span class="p">(</span><span class="n">ReportBand</span><span class="p">):</span>
        <span class="n">height</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span>
        <span class="n">elements</span><span class="o">=</span><span class="p">(</span>
            <span class="n">ObjectValue</span><span class="p">(</span><span class="n">attribute_name</span><span class="o">=</span><span class="s">&#39;id&#39;</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mf">0.5</span><span class="o">*</span><span class="n">cm</span><span class="p">),</span>
            <span class="n">ObjectValue</span><span class="p">(</span><span class="n">attribute_name</span><span class="o">=</span><span class="s">&#39;date_creation&#39;</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mi">3</span><span class="o">*</span><span class="n">cm</span><span class="p">,</span>
                <span class="n">get_value</span><span class="o">=</span><span class="k">lambda</span> <span class="n">instance</span><span class="p">:</span> <span class="n">instance</span><span class="o">.</span><span class="n">date_creation</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">&#39;%m/</span><span class="si">%d</span><span class="s">/%Y&#39;</span><span class="p">)),</span>
            <span class="p">)</span>
</pre></div>
</div>
<p>The attribute <strong>band_detail</strong> is locally declared as a class, but it could alternatively be set
with an external class.</p>
<p>The important thing here is that the band has the attribute <strong>height</strong>, fixed with a
defined height in centimeters.</p>
<p>The second thing to observe is the <strong>elements</strong> list, with 2 widgets representing
2 model class fields: <strong>id</strong> and <strong>date_creation</strong>. The last one is customized
with the <strong>get_value</strong> attribute, for date field formatting.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="index.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="">Tutorial using Web2Py</a><ul>
<li><a class="reference external" href="#step-1-preparing-your-project">Step 1. Preparing your project</a></li>
<li><a class="reference external" href="#declaring-the-report-class">Declaring the report class</a></li>
<li><a class="reference external" href="#detail-band">Detail band</a></li>
</ul>
</li>
</ul>

            <h4>Previous topic</h4>
            <p class="topless"><a href="tutorial-1.html"
                                  title="previous chapter">Tutorial using Django</a></p>
            <h4>Next topic</h4>
            <p class="topless"><a href="basic.html"
                                  title="next chapter">Basic Reference</a></p>
            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="_sources/tutorial-2.txt"
                     rel="nofollow">Show Source</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Quick search</h3>
              <form class="search" action="search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Enter search terms or a module, class or function name.
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="basic.html" title="Basic Reference"
             >next</a> |</li>
        <li class="right" >
          <a href="tutorial-1.html" title="Tutorial using Django"
             >previous</a> |</li>
        <li><a href="index.html">Geraldo Reports Documentation v0.4-alpha-6 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright 2009-2010, Marinho Brandao.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.3.
    </div>
  </body>
</html>